var editor;
var jarFilePath;
var contentConsole;
var myFunction={};
var fh={}; //自定义方法调用对象
$(function(){

    $(".cover-content").hide();
    contentConsole = $(".result-content");

    function collectConnectionInfo(){
        var info = {
            "jdbc.driver.jarfile":jarFilePath,
            "jdbc.driver.driverClass":$("#classNameTextField").val(),
            "jdbc.driver.url":$("#connectionTextField").val(),
            "jdbc.driver.user":$("#usernameTextField").val(),
            "jdbc.driver.key":$("#passwordTextField").val(),
            "ssh.host":$("#sshIpTextField").val(),
            "ssh.port":$("#sshPortTextField").val(),
            "ssh.user":$("#sshUsernameTextField").val(),
            "ssh.password":$("#sshPasswordTextField").val(),
            "proxy.host":$("#proxyIpTextField").val(),
            "proxy.port":$("#proxyPortTextField").val(),
            "target.host":$("#targetIpTextField").val(),
            "target.port":$("#targetPortTextField").val()
        };
        sqlUtil.putConnectionInfo(info);
    }

    function initParams(){
        var initParam = sqlUtil.getConnectionProperty();
        jarFilePath = initParam["jdbc.driver.jarfile"];
        $("#jarFileTextField").val(jarFilePath?(jarFilePath.substring(jarFilePath.lastIndexOf("/")+1)):"");
        $("#classNameTextField").val(initParam["jdbc.driver.driverClass"]);
        $("#connectionTextField").val(initParam["jdbc.driver.url"]);
        $("#usernameTextField").val(initParam["jdbc.driver.user"]);
        $("#passwordTextField").val(initParam["jdbc.driver.key"]);
        $("#sshIpTextField").val(initParam["ssh.host"]);
        $("#sshPortTextField").val(initParam["ssh.port"]||"22");
        $("#sshUsernameTextField").val(initParam["ssh.user"]);
        $("#sshPasswordTextField").val(initParam["ssh.password"]);
        $("#proxyIpTextField").val(initParam["proxy.host"]);
        $("#proxyPortTextField").val(initParam["proxy.port"]);
        $("#targetIpTextField").val(initParam[ "target.host"]);
        $("#targetPortTextField").val(initParam["target.port"]);
        $("#configFileText").text(sqlUtil.getConfigFileName());
    }

    var mode = "text/javascript";
    var textArea;
    editor = CodeMirror.fromTextArea(textArea=document.getElementById("codeTextArea"), {
        mode: mode,
        styleActiveLine: true,
        lineNumbers: true,
        lineWrapping: false
    });
    textArea = $(textArea);

    var execBtn = appendToolsBtn("执行","class='success-btn'").click(function(){
        editor.save();
        var code = textArea.val();
        try{
            eval(code);
        }catch (e) {
            println(createErrInfo(e));
        }
    });

    $("#jarFileTextField").click(function(){
        var file = fileUtil.selectFile(['*.jar']);
        if(file){
            jarFilePath = file.path;
            $(this).val(file.fileName);
        }
    });

    $("#chooseConfigBtn").click(function(){
        var file = fileUtil.selectFile(['*.properties']);
        if(file!=null){
            sqlUtil.setConfigPath(file.path);
            sqlUtil.reloadProperty();
            initParams();
        }
    });

    $("#saveAsConfigBtn").click(function(){
        var file = fileUtil.selectFileForSave(['*.properties']);
        if(file!=null){
            sqlUtil.setConfigPath(file.path);
            $("#applyConnectionInfoBtn").click();
        }
    });

    $("#applyConnectionInfoBtn").click(function () {
        try{
            collectConnectionInfo();
            new MessageBody("消息","数据库连接信息设置成功！",2000).showMessage();
        }catch (e) {
            collectConnectionInfo();
            new MessageBody("消息","数据库连接信息设置失败！",2000).showMessage();
        }
    });

    $("#testConnectionBtn").click(function(){
        $(".cover-content").show();
        var process = $(".process-root").createProcess({total:5,val:-1,loadingText:'尝试连接...'});
        var dialog;
        var stop;
        var id = setTimeout(function(){
            dialog = createDialog({title:'错误消息',content:'连接好像有了问题，等待时间过长，要不检查一下连接信息？',type:'error',okAction:function(){
                stop = true;
                sqlUtil.disConnection();
                process.setLoadingText("请等待进程结束...");
            }});
            dialog.show();
        },5000)
        sqlUtil.testConnection(function(state,msg){
            process.destroy();
            $(".cover-content").hide();
            clearTimeout(id);
            if(!stop){
                if(state == 1) new MessageBody("消息","数据库连接成功！",2000).showMessage();
                else new MessageBody("消息","数据库连接失败:"+msg,2000).showMessage();
            }
            if(dialog) dialog.destroy();
        });
    });

    onBackRequest = function(){
        sqlUtil.disConnection();
    }

    initParams();

    var keepPress = false;
    $(document).bind('keyup',function(){
        keepPress = false;
    });
    $(document).bind('keydown',function(e){
        if(e.keyCode==82 && e.ctrlKey && !keepPress){
            keepPress=true;
            execBtn.click();
        }
    });
    execBtn[0].title="CTRL+R";

    try{
        var funcs = sqlUtil.readFunctionCode();
        if(typeof funcs === 'object'){
            for(var i in funcs){
                myFunction[i]=funcs[i];
                eval("fh['"+i+"']="+funcs[i]);
            }
        }
    }catch (e) {
        println(createErrInfo("初始化方法问题："+e));
    }
})

function consoleToBottom01001(){
    var c = $(".result-content");
    c.scrollTop(c[0].scrollHeight);
}

function createErrInfo(info){
    return "<span style='color:#F00;'>"+info+"</span>";
}

function print(info){
    contentConsole.html(contentConsole.html()+(info==null?"":info.toString()));
    consoleToBottom01001();
}
function println(info){
    contentConsole.html(contentConsole.html()+"<br>"+(info==null?"":info.toString()));
    consoleToBottom01001();
}

function clear(){
    contentConsole.html('');
}

function printTable(info){
    if(!info) return;
    if(info.infotype !== 'queryInfo') {
        println(createErrInfo("不是query类型！"));
        return;
    }
    if(!info.infoData) {
        println("table无数据！");
        return;
    }
    var arrTitle = info.infoData.column;
    var arrValue = info.infoData.value;
    var html='<table>';
    html+='<thead>';
    html+='<tr>';
    arrTitle.forEach(function(v){
       html+='<th>'+v+'</th>';
    });
    html+='</tr>';
    html+='</thread>';
    html+='<tbody>';
    arrValue.forEach(function(v){
        if(v){
            html+='<tr>'
            v.forEach(function(s){
                html+='<td>'+(s==null?"":htmlEncode(s))+'</td>';
            });
            html+='</tr>';
        }
    });
    html+='</tbody>';
    html+='</table>';
    println(html);
}

function printJson(obj){
    println(_createHtmlJson01001(obj));
}

function _createHtmlJson01001(obj,count,isArray){
    var html="";
    if(obj == null){
        if(isArray){
            html+="<span class='json' style='color:#abc38c;'>null</span>";
        }else{
            html+="<span class='json' style='color:#cb3d12;'>null</span>";
        }
        return html;
    }
    count=count||0;
    //数组
    var endSpace = _printSpace01001(count);
    count+=4;
    var space = _printSpace01001(count);
    if(obj.constructor === Array){
        html +="[<br/>"
        for(var i=0;i<obj.length;i++){
            if(i) html+=",<br/>";
            html += space+_createHtmlJson01001(obj[i],count,true);
        }
        html+="<br/>"+endSpace+"]";
    }
    //string
    else if(typeof obj === 'string'){
        if(isArray){
            html+="<span class='json' style='color:#abc38c;'>\""+htmlEncode(obj)+"\"</span>";
        }else{
            html+="<span class='json' style='color:#29a4d4;'>\""+htmlEncode(obj)+"\"</span>";
        }
    }
    //数字类型
    else if(typeof obj === 'number' || typeof obj === 'boolean'){
        if(isArray){
            html+="<span class='json' style='color:#abc38c;'>"+obj+"</span>";
        }else{
            if(typeof obj === 'number'){
                html+="<span class='json' style='color:#543db5;'>"+obj+"</span>";
            }else{
                html+="<span class='json' style='color:#cb3d12;'>"+obj+"</span>";
            }
        }
    }
    //对象
    else if(typeof obj === 'object'){
        html+="{<br/>";
        var first = true;
        for(var i in obj){
            if(!first) html+=",<br/>";
            html+=space+"<span class='json' style='color:#3a9c4e;'>"+i+"</span>"+":"+_createHtmlJson01001(obj[i],count);
            first = false;
        }
        html+="<br/>"+endSpace+"}"
    }
    return html;
}
function _printSpace01001(count){
    var s="";
    while(count>0) {
        s+="&nbsp;";
        count--;
    }
    return s;
}

function createFunction(name,func){
    if(!name){
        println(createErrInfo("需要指定方法名！"));
        return;
    }
    if(typeof func !== 'function'){
        println(createErrInfo("只有方法才可以被创建！"));
        return;
    }
    if(myFunction[name]){
        println(createErrInfo("方法已存在！"));
        return;
    }
    myFunction[name]=func.toString();
    fh[name]=func;
    try{
        sqlUtil.saveFunctionCode(myFunction);
        new MessageBody("消息","创建function成功！",2000).showMessage();
    }catch (e) {
        delete myFunction[name];
        delete fh[name];
        new MessageBody("错误","创建function失败:"+e,2000).showMessage();
    }
}

function dropFunction(name){
    if(!myFunction[name]){
        println(createErrInfo("方法不存在！"));
        return;
    }
    var o1=myFunction[name],o2=fh[name];
    delete myFunction[name];
    delete fh[name];
    try{
        sqlUtil.saveFunctionCode(myFunction);
        new MessageBody("消息","删除function成功！",2000).showMessage();
    }catch (e) {
        myFunction[name]=o1;
        fh[name]=o2;
        new MessageBody("错误","删除function失败:"+e,2000).showMessage();
    }
}

function createInParam(z,arr,map){
    if(typeof z !== 'boolean'){
        map = arr;
        arr=z;
        z=true;
    }
    var s=" ( ";
    $.each(arr,function(i,v){
        if(i>0) s+=","
        if(z){
            v="?";
        }else{
            if(map) v = map(v);
        }
        s+=v;
    });
    s+=' ) ';
    return s;
}

function printApi(){
    println(createErrInfo('以下被声明的方法/属性不要被覆盖其他变量，否则无法使用！'));
    printTable({
        infotype:'queryInfo',
        infoData:{
            column:['方法/属性','说明'],
            value:[
                ['print(param)','不换行的输出'],
                ['println(param)','换行输出'],
                ['createErrInfo(param)','print(createErrInfo(param))，一般用作错误输出信息，简单的加了<span>标签。'],
                ['clear()','清空控制台'],
                ['printTable(param)','可以将sql的查询结果打印为table'],
                ['printJson(param)','打印格式化json'],
                ['printApi','输出帮助信息'],
                ['sqlUtil.execSql(sql,[params])','执行sql语句，可以使用?代替参数，如果无参数，params可省略。params是数组类型。'],
                ['sqlUtil.commit()','如果执行了更新或插入删除操作，必须提交才可以生效'],
                ['sqlUtil.rollback()','回滚事务，遇到异常时可保证事务完整性'],
                ['sqlUtil.disConnection()','关闭连接，如果再次执行了sql则自动打开一个新的连接'],
                ['htmlEncode(str)','将html标签转为转义符。'],
                ['htmlDecode(str)','将转义符转为html标签'],
                ['createFunction(name,func)','创建自定义方法，下次启动时并可以访问'],
                ['dropFunction(name)','删除自定义方法'],
                ['fh','访问自定义方法对象，fh.diyFunction()的方式去调用。diyFunction为方法名。'],
                ['createInParam(z,arr,map)','创建一个in查询sql参数列表，返回(?,?)这样的字符。z默认为true，表示用?代替参数。z和map可省略。z为false map才会生效。']
            ]
        }
    });
}